<!DOCTYPE html>
<html lang="en">
  <head>
    <title>
        Java-framework-Spring-Data-JPA - rulerLwx Blog
      </title>
        <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport"
      content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, minimal-ui">
    <meta name="renderer" content="webkit">
    <meta http-equiv="Cache-Control" content="no-transform" />
    <meta http-equiv="Cache-Control" content="no-siteapp" />
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <meta name="format-detection" content="telephone=no,email=no,adress=no">
    
    <meta name="theme-color" content="#000000" />
    
    <meta http-equiv="window-target" content="_top" />
    
    
    <meta name="description" content="概述 Spring Data JPA 底层使用 Hibernate JPA 来实现（所以要导入 Hibernate 相关包）。 Spring Data JPA 技术特点：只需要定义接口并继承 Spring Data JPA 提供的接口就行，不需要写接口实现类。 官方示例 官" />
    <meta name="generator" content="Hugo 0.73.0 with theme pure" />
    <title>Java-framework-Spring-Data-JPA - rulerLwx Blog</title>
    
    
    <link rel="stylesheet" href="https://rulerLwx.gitee.io/css/style.min.c4bc7071f132c964c2116bca53b392933f377e5ca7b7051ed245187c621a2d3e.css">
    
    <link rel="stylesheet" href="https://cdn.staticfile.org/highlight.js/9.15.10/styles/github.min.css" async>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.4.2/tocbot.css" async>
    <meta property="og:title" content="Java-framework-Spring-Data-JPA" />
<meta property="og:description" content="概述 Spring Data JPA 底层使用 Hibernate JPA 来实现（所以要导入 Hibernate 相关包）。 Spring Data JPA 技术特点：只需要定义接口并继承 Spring Data JPA 提供的接口就行，不需要写接口实现类。 官方示例 官" />
<meta property="og:type" content="article" />
<meta property="og:url" content="https://rulerLwx.gitee.io/2019/08/java-framework-spring-data-jpa/" />
<meta property="article:published_time" content="2019-08-17T11:10:30+08:00" />
<meta property="article:modified_time" content="2019-08-17T11:10:30+08:00" />
<meta itemprop="name" content="Java-framework-Spring-Data-JPA">
<meta itemprop="description" content="概述 Spring Data JPA 底层使用 Hibernate JPA 来实现（所以要导入 Hibernate 相关包）。 Spring Data JPA 技术特点：只需要定义接口并继承 Spring Data JPA 提供的接口就行，不需要写接口实现类。 官方示例 官">
<meta itemprop="datePublished" content="2019-08-17T11:10:30&#43;08:00" />
<meta itemprop="dateModified" content="2019-08-17T11:10:30&#43;08:00" />
<meta itemprop="wordCount" content="4949">



<meta itemprop="keywords" content="" /><meta name="twitter:card" content="summary"/>
<meta name="twitter:title" content="Java-framework-Spring-Data-JPA"/>
<meta name="twitter:description" content="概述 Spring Data JPA 底层使用 Hibernate JPA 来实现（所以要导入 Hibernate 相关包）。 Spring Data JPA 技术特点：只需要定义接口并继承 Spring Data JPA 提供的接口就行，不需要写接口实现类。 官方示例 官"/>

    <!--[if lte IE 9]>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/classlist/1.1.20170427/classList.min.js"></script>
      <![endif]-->

    <!--[if lt IE 9]>
        <script src="https://cdn.jsdelivr.net/npm/html5shiv@3.7.3/dist/html5shiv.min.js"></script>
        <script src="https://cdn.jsdelivr.net/npm/respond.js@1.4.2/dest/respond.min.js"></script>
      <![endif]-->
  </head>

  
  

  <body class="main-center theme-black" itemscope itemtype="http://schema.org/WebPage"><header class="header" itemscope itemtype="http://schema.org/WPHeader">
    <div class="slimContent">
      <div class="navbar-header">
        <div class="profile-block text-center">
          <a id="avatar" href="https://gitee.com/rulerLwx" target="_blank">
            <img class="img-circle img-rotate" src="https://rulerLwx.gitee.io/avatar.png" width="200" height="200">
          </a>
          <h2 id="name" class="hidden-xs hidden-sm">rulerLwx</h2>
          <h3 id="title" class="hidden-xs hidden-sm hidden-md">thinking...</h3>
          <small id="location" class="text-muted hidden-xs hidden-sm"><i class="icon icon-map-marker"></i>Guangzhou, China</small>
        </div><div class="search" id="search-form-wrap">
    <form class="search-form sidebar-form">
        <div class="input-group">
            <input type="text" class="search-form-input form-control" placeholder="Search" />
            <span class="input-group-btn">
                <button type="submit" class="search-form-submit btn btn-flat" onclick="return false;"><i
                        class="icon icon-search"></i></button>
            </span>
        </div>
        <div class="ins-search">
            <div class="ins-search-mask"></div>
            <div class="ins-search-container">
                <div class="ins-input-wrapper">
                    <input type="text" class="ins-search-input" placeholder="Type something..."
                        x-webkit-speech />
                    <button type="button" class="close ins-close ins-selectable" data-dismiss="modal"
                        aria-label="Close"><span aria-hidden="true">×</span></button>
                </div>
                <div class="ins-section-wrapper">
                    <div class="ins-section-container"></div>
                </div>
            </div>
        </div>
    </form>
</div>
        <button class="navbar-toggle collapsed" type="button" data-toggle="collapse" data-target="#main-navbar" aria-controls="main-navbar" aria-expanded="false">
          <span class="sr-only">Toggle navigation</span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
        </button>
      </div>
      <nav id="main-navbar" class="collapse navbar-collapse" itemscope itemtype="http://schema.org/SiteNavigationElement" role="navigation">
        <ul class="nav navbar-nav main-nav">
            <li class="menu-item menu-item-home">
                <a href="/">
                    <i class="icon icon-home-fill"></i>
                  <span class="menu-title">Home</span>
                </a>
            </li>
            <li class="menu-item menu-item-archives">
                <a href="/posts/">
                    <i class="icon icon-archives-fill"></i>
                  <span class="menu-title">Archives</span>
                </a>
            </li>
            <li class="menu-item menu-item-categories">
                <a href="/categories/">
                    <i class="icon icon-folder"></i>
                  <span class="menu-title">Categories</span>
                </a>
            </li>
            <li class="menu-item menu-item-tags">
                <a href="/tags/">
                    <i class="icon icon-tags"></i>
                  <span class="menu-title">Tags</span>
                </a>
            </li>
            <li class="menu-item menu-item-about">
                <a href="/about/">
                    <i class="icon icon-cup-fill"></i>
                  <span class="menu-title">About</span>
                </a>
            </li>
        </ul>
      </nav>
    </div>
  </header>

<aside class="sidebar" itemscope itemtype="http://schema.org/WPSideBar">
  <div class="slimContent">
    
      <div class="widget">
    <h3 class="widget-title">Board</h3>
    <div class="widget-body">
        <div id="board">
            <div class="content">enjoy~
            </div>
        </div>
    </div>
</div>

      <div class="widget">
    <h3 class="widget-title"> Categories</h3>
    <div class="widget-body">
        <ul class="category-list">
            <li class="category-list-item"><a href="https://rulerLwx.gitee.io/categories/java-framework/" class="category-list-link">java-framework</a><span class="category-list-count">38</span></li>
            <li class="category-list-item"><a href="https://rulerLwx.gitee.io/categories/java-front-end/" class="category-list-link">java-front-end</a><span class="category-list-count">11</span></li>
            <li class="category-list-item"><a href="https://rulerLwx.gitee.io/categories/java-se/" class="category-list-link">java-se</a><span class="category-list-count">21</span></li>
            <li class="category-list-item"><a href="https://rulerLwx.gitee.io/categories/java-senior/" class="category-list-link">java-senior</a><span class="category-list-count">4</span></li>
            <li class="category-list-item"><a href="https://rulerLwx.gitee.io/categories/linux/" class="category-list-link">linux</a><span class="category-list-count">13</span></li>
            <li class="category-list-item"><a href="https://rulerLwx.gitee.io/categories/tools/" class="category-list-link">tools</a><span class="category-list-count">1</span></li>
            <li class="category-list-item"><a href="https://rulerLwx.gitee.io/categories/%E6%8A%80%E6%9C%AF%E6%9D%82%E7%83%A9/" class="category-list-link">技术杂烩</a><span class="category-list-count">4</span></li>
            <li class="category-list-item"><a href="https://rulerLwx.gitee.io/categories/%E6%95%B0%E6%8D%AE%E5%BA%93/" class="category-list-link">数据库</a><span class="category-list-count">15</span></li>
        </ul>
    </div>
</div>
      <div class="widget">
    <h3 class="widget-title"> Tags</h3>
    <div class="widget-body">
        <ul class="tag-list">
            
            
            <li class="tag-list-item"><a href="https://rulerLwx.gitee.io/tags/jvm/" class="tag-list-link">jvm</a><span
                    class="tag-list-count">1</span></li>
            
            
            <li class="tag-list-item"><a href="https://rulerLwx.gitee.io/tags/%E5%A4%9A%E7%BA%BF%E7%A8%8B/" class="tag-list-link">多线程</a><span
                    class="tag-list-count">2</span></li>
            
            
            <li class="tag-list-item"><a href="https://rulerLwx.gitee.io/tags/%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B/" class="tag-list-link">网络编程</a><span
                    class="tag-list-count">3</span></li>
            
        </ul>

    </div>
</div>
      
<div class="widget">
    <h3 class="widget-title">Recent Posts</h3>
    <div class="widget-body">
        <ul class="recent-post-list list-unstyled no-thumbnail">
            <li>
                <div class="item-inner">
                    <p class="item-title">
                        <a href="https://rulerLwx.gitee.io/2020/07/%E8%87%AA%E5%B7%B1%E5%8A%A8%E6%89%8B%E4%B8%80%E6%89%B9%E9%87%8F%E7%A7%BB%E5%8A%A8%E9%87%8D%E5%91%BD%E5%90%8D%E6%96%87%E4%BB%B6/" class="title">自己动手（一）——批量移动、重命名文件</a>
                    </p>
                    <p class="item-date">
                        <time datetime="2020-07-27 17:50:02 &#43;0800 CST" itemprop="datePublished">2020-07-27</time>
                    </p>
                </div>
            </li>
            <li>
                <div class="item-inner">
                    <p class="item-title">
                        <a href="https://rulerLwx.gitee.io/2020/07/%E5%85%B3%E4%BA%8Einteger%E7%9A%84-128~127%E7%BC%93%E5%AD%98/" class="title">关于Integer的 -128~127缓存</a>
                    </p>
                    <p class="item-date">
                        <time datetime="2020-07-11 16:56:21 &#43;0800 CST" itemprop="datePublished">2020-07-11</time>
                    </p>
                </div>
            </li>
            <li>
                <div class="item-inner">
                    <p class="item-title">
                        <a href="https://rulerLwx.gitee.io/2020/07/%E8%B7%A8%E5%9F%9F%E9%97%AE%E9%A2%98/" class="title">跨域问题</a>
                    </p>
                    <p class="item-date">
                        <time datetime="2020-07-08 22:41:12 &#43;0800 CST" itemprop="datePublished">2020-07-08</time>
                    </p>
                </div>
            </li>
            <li>
                <div class="item-inner">
                    <p class="item-title">
                        <a href="https://rulerLwx.gitee.io/2020/07/%E4%B8%AA%E4%BA%BA%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA/" class="title">个人博客搭建</a>
                    </p>
                    <p class="item-date">
                        <time datetime="2020-07-05 18:58:47 &#43;0800 CST" itemprop="datePublished">2020-07-05</time>
                    </p>
                </div>
            </li>
            <li>
                <div class="item-inner">
                    <p class="item-title">
                        <a href="https://rulerLwx.gitee.io/2020/07/mongodb-1/" class="title">MonggoDB-1</a>
                    </p>
                    <p class="item-date">
                        <time datetime="2020-07-03 18:58:47 &#43;0800 CST" itemprop="datePublished">2020-07-03</time>
                    </p>
                </div>
            </li>
        </ul>
    </div>
</div>
  </div>
</aside>

    
    
<aside class="sidebar sidebar-toc collapse" id="collapseToc" itemscope itemtype="http://schema.org/WPSideBar">
  <div class="slimContent">
    <h4 class="toc-title">Catalogue</h4>
    <nav id="toc" class="js-toc toc">

    </nav>
  </div>
</aside>
<main class="main" role="main"><div class="content">
  <article id="-" class="article article-type-" itemscope
    itemtype="http://schema.org/BlogPosting">
    
    <div class="article-header">
      <h1 itemprop="name">
  <a
    class="article-title"
    href="/2019/08/java-framework-spring-data-jpa/"
    >Java-framework-Spring-Data-JPA</a
  >
</h1>

      <div class="article-meta">
        
<span class="article-date">
  <i class="icon icon-calendar-check"></i>&nbsp;
<a href="https://rulerLwx.gitee.io/2019/08/java-framework-spring-data-jpa/" class="article-date">
  <time datetime="2019-08-17 11:10:30 &#43;0800 CST" itemprop="datePublished">2019-08-17</time>
</a>
</span>
<span class="article-category">
  <i class="icon icon-folder"></i>&nbsp;
  <a class="article-category-link" href="/categories/java-framework/"> Java-framework </a>
</span>

        <span class="post-comment"><i class="icon icon-comment"></i>&nbsp;<a href="/2019/08/java-framework-spring-data-jpa/#comments"
            class="article-comment-link">Comments</a></span>
		<span class="post-wordcount hidden-xs" itemprop="wordCount">Word Count: 4949words</span>
		<span class="post-readcount hidden-xs" itemprop="timeRequired">Read Count: 10minutes </span>
      </div>
    </div>
    <div class="article-entry marked-body js-toc-content" itemprop="articleBody">
      <h1 id="概述">概述</h1>
<p>Spring Data JPA 底层使用 Hibernate JPA 来实现（所以<strong>要导入 Hibernate 相关包</strong>）。</p>
<p>Spring Data JPA 技术特点：只需要定义接口并继承 Spring Data JPA 提供的接口就行，不需要写接口实现类。</p>
<h1 id="官方示例">官方示例</h1>
<p>官方示例代码：https://github.com/spring-projects/spring-data-examples</p>
<p>PS：官方示例并没有导入 Hibernate 相关包，但自己的示例中要导入。</p>
<h1 id="博客">博客</h1>
<p><a href="https://www.cnblogs.com/dreamroute/p/5173896.html">https://www.cnblogs.com/dreamroute/p/5173896.html</a></p>
<p><a href="https://www.cnblogs.com/zeng1994/p/7575606.html">https://www.cnblogs.com/zeng1994/p/7575606.html</a></p>
<h1 id="入门示例">入门示例</h1>
<h2 id="步骤一导入依赖">步骤一：导入依赖</h2>
<p>父pom，使用了BOM，子模块相关项不用写版本</p>
<pre><code class="language-xml">    &lt;properties&gt;
        &lt;java.version&gt;1.8&lt;/java.version&gt;
        &lt;spring.version&gt;4.3.24.RELEASE&lt;/spring.version&gt;
        &lt;spring-data.version&gt;Ingalls-SR22&lt;/spring-data.version&gt;
    &lt;/properties&gt;

    &lt;dependencyManagement&gt;
        &lt;dependencies&gt;
            &lt;dependency&gt;
                &lt;groupId&gt;org.springframework&lt;/groupId&gt;
                &lt;artifactId&gt;spring-framework-bom&lt;/artifactId&gt;
                &lt;version&gt;${spring.version}&lt;/version&gt;
                &lt;scope&gt;import&lt;/scope&gt;
                &lt;type&gt;pom&lt;/type&gt;
            &lt;/dependency&gt;
            &lt;dependency&gt;
                &lt;groupId&gt;org.springframework.data&lt;/groupId&gt;
                &lt;artifactId&gt;spring-data-releasetrain&lt;/artifactId&gt;
                &lt;version&gt;${spring-data.version}&lt;/version&gt;
                &lt;scope&gt;import&lt;/scope&gt;
                &lt;type&gt;pom&lt;/type&gt;
            &lt;/dependency&gt;
        &lt;/dependencies&gt;
    &lt;/dependencyManagement&gt;
</code></pre>
<p>子模块：</p>
<pre><code class="language-xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot;
         xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
         xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd&quot;&gt;
    &lt;parent&gt;
        &lt;artifactId&gt;spring-data-demo&lt;/artifactId&gt;
        &lt;groupId&gt;com.demo&lt;/groupId&gt;
        &lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;
    &lt;/parent&gt;
    &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;

    &lt;artifactId&gt;spring-data-jpa&lt;/artifactId&gt;

    &lt;properties&gt;
        &lt;hibernate.version&gt;5.0.12.Final&lt;/hibernate.version&gt;
    &lt;/properties&gt;

    &lt;dependencies&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.springframework.data&lt;/groupId&gt;
            &lt;artifactId&gt;spring-data-jpa&lt;/artifactId&gt;
        &lt;/dependency&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;com.mchange&lt;/groupId&gt;
            &lt;artifactId&gt;c3p0&lt;/artifactId&gt;
            &lt;version&gt;0.9.5.4&lt;/version&gt;
        &lt;/dependency&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;junit&lt;/groupId&gt;
            &lt;artifactId&gt;junit&lt;/artifactId&gt;
            &lt;version&gt;4.12&lt;/version&gt;
        &lt;/dependency&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.springframework&lt;/groupId&gt;
            &lt;artifactId&gt;spring-test&lt;/artifactId&gt;
        &lt;/dependency&gt;
        &lt;!--hibernate--&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.hibernate&lt;/groupId&gt;
            &lt;artifactId&gt;hibernate-core&lt;/artifactId&gt;
            &lt;version&gt;${hibernate.version}&lt;/version&gt;
        &lt;/dependency&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.hibernate&lt;/groupId&gt;
            &lt;artifactId&gt;hibernate-entitymanager&lt;/artifactId&gt;
            &lt;version&gt;${hibernate.version}&lt;/version&gt;
        &lt;/dependency&gt;
        &lt;!--mysql drive--&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;mysql&lt;/groupId&gt;
            &lt;artifactId&gt;mysql-connector-java&lt;/artifactId&gt;
            &lt;version&gt;5.1.19&lt;/version&gt;
        &lt;/dependency&gt;
    &lt;/dependencies&gt;

&lt;/project&gt;
</code></pre>
<p>注意版本的要求：http://hibernate.org/orm/documentation/getting-started/</p>
<pre><code class="language-txt">Hibernate 5.2 and later versions require at least Java 1.8 and JDBC 4.2.
Hibernate 5.1 and older versions require at least Java 1.6 and JDBC 4.0.
</code></pre>
<h2 id="步骤二spring配置文件">步骤二：Spring配置文件</h2>
<pre><code class="language-xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
       xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
       xmlns:context=&quot;http://www.springframework.org/schema/context&quot; xmlns:tx=&quot;http://www.springframework.org/schema/tx&quot;
       xmlns:jpa=&quot;http://www.springframework.org/schema/data/jpa&quot;
       xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd&quot;&gt;

    &lt;context:property-placeholder location=&quot;classpath:jdbc.properties&quot;/&gt;
    &lt;!-- 配置c3p0 数据库连接池--&gt;
    &lt;bean id=&quot;dataSource&quot;
          class=&quot;com.mchange.v2.c3p0.ComboPooledDataSource&quot;&gt;
        &lt;property name=&quot;jdbcUrl&quot; value=&quot;${jdbc.mysql.url}&quot;/&gt;
        &lt;property name=&quot;driverClass&quot; value=&quot;${jdbc.mysql.driverClass}&quot;/&gt;
        &lt;property name=&quot;user&quot; value=&quot;${jdbc.mysql.user}&quot;/&gt;
        &lt;property name=&quot;password&quot; value=&quot;${jdbc.mysql.password}&quot;/&gt;
    &lt;/bean&gt;
    &lt;!-- Spring 整合JPA 配置EntityManagerFactory--&gt;
    &lt;bean id=&quot;entityManagerFactory&quot;
          class=&quot;org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean&quot;&gt;
        &lt;property name=&quot;dataSource&quot; ref=&quot;dataSource&quot;/&gt;
        &lt;property name=&quot;jpaVendorAdapter&quot;&gt;
            &lt;bean class=&quot;org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter&quot;&gt;
                &lt;!-- hibernate 相关的属性的注入--&gt;
                &lt;!-- 配置数据库类型--&gt;
                &lt;property name=&quot;database&quot; value=&quot;MYSQL&quot;/&gt;
                &lt;!-- 正向工程自动创建表--&gt;
                &lt;property name=&quot;generateDdl&quot; value=&quot;true&quot;/&gt;
                &lt;!-- 显示执行的SQL --&gt;
                &lt;property name=&quot;showSql&quot; value=&quot;true&quot;/&gt;
            &lt;/bean&gt;
        &lt;/property&gt;
        &lt;!-- 扫描实体的包--&gt;
        &lt;property name=&quot;packagesToScan&quot;&gt;
            &lt;list&gt;
                &lt;value&gt;com.demo.pojo&lt;/value&gt;
            &lt;/list&gt;
        &lt;/property&gt;
    &lt;/bean&gt;
    &lt;!-- 配置Hibernate 的事务管理器--&gt;
    &lt;bean id=&quot;transactionManager&quot; class=&quot;org.springframework.orm.jpa.JpaTransactionManager&quot;&gt;
        &lt;property name=&quot;entityManagerFactory&quot; ref=&quot;entityManagerFactory&quot;/&gt;
    &lt;/bean&gt;
    &lt;!-- 配置开启注解事务处理--&gt;
    &lt;tx:annotation-driven transaction-manager=&quot;transactionManager&quot;/&gt;
    &lt;!-- 配置springIOC 的注解扫描--&gt;
    &lt;context:component-scan base-package=&quot;com.demo&quot;/&gt;
    &lt;!-- Spring Data JPA 的配置--&gt;
    &lt;!-- base-package：扫描dao 接口所在的包--&gt;
    &lt;jpa:repositories base-package=&quot;com.demo.dao&quot;/&gt;
&lt;/beans&gt;
</code></pre>
<pre><code class="language-properties">jdbc.mysql.driverClass=com.mysql.jdbc.Driver
jdbc.mysql.url=jdbc:mysql://localhost:3306/test
jdbc.mysql.user=root
jdbc.mysql.password=root
</code></pre>
<h2 id="步骤三写dao和实体类">步骤三：写DAO和实体类</h2>
<pre><code class="language-java">public interface UserDao extends JpaRepository&lt;User,Integer&gt; {

    /**
     * JpaRepository&lt;T,D&gt;，T表示对应哪个实体，D表示实体的id类型
     */
}
</code></pre>
<pre><code class="language-java">@Entity
@Table(name=&quot;user&quot;)
public class User implements Serializable{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = &quot;id&quot;)
    private Integer id;
    @Column(name = &quot;name&quot;)
    private String name;

    //omitted for set/get/toString
}
</code></pre>
<h2 id="步骤四测试">步骤四：测试</h2>
<pre><code class="language-java">@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(&quot;classpath:applicationContext.xml&quot;)
public class UsersDaoImplTest {
    @Autowired
    private UserDao usersDao;
    /**
     * 添加用户
     */
    @Test
    @Transactional// 在测试类对于事务提交方式默认的是回滚。
    @Rollback(false)//取消自动回滚
    public void testInsertUsers(){
        User user = new User();
        user.setName(&quot;张三丰&quot;);
        this.usersDao.save(user);
    }
}
</code></pre>
<h1 id="底层原理">底层原理</h1>
<h2 id="jparepository-接口继承结构">JpaRepository 接口继承结构</h2>
<p><img src="https://gitee.com/rulerLwx/PicGo/raw/master/img/20200708092347.png" alt=""></p>
<p>org.springframework.data.repository.CrudRepository.save()方法有增加、更新两重意思。</p>
<h2 id="dao接口不写实现的原理">DAO接口不写实现的原理</h2>
<pre><code class="language-java">@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(&quot;classpath:applicationContext.xml&quot;)
public class UsersDaoImplTest {
    @Autowired
    private UserDao usersDao;

    @Test
    public void test(){
        //org.springframework.data.jpa.repository.support.SimpleJpaRepository@2ab2710
        System.out.println(this.usersDao);
        //class com.sun.proxy.$Proxy29
        System.out.println(this.usersDao.getClass());
    }
}
</code></pre>
<p>UserDao 接口是 SimpleJpaRepository 的代理。</p>
<h1 id="repository-接口">Repository 接口</h1>
<p>Repository 接口是Spring Data JPA 中为我们提供的所有接口中的顶层接口</p>
<p>Repository 提供了两种查询方式的支持</p>
<ul>
<li>1）基于方法名称命名规则查询</li>
<li>2）基于@Query 注解查询</li>
</ul>
<h2 id="1基于方法名称命名规则查询">1）基于方法名称命名规则查询</h2>
<p>命名规则：findBy(关键字)+属性名称(属性名称的首字母大写)+查询条件(首字母大写)</p>
<table>
<thead>
<tr>
<th>关键字</th>
<th>方法命名</th>
<th>sql where 字句</th>
</tr>
</thead>
<tbody>
<tr>
<td>And</td>
<td>findByNameAndPwd</td>
<td>where name= ? and pwd =?</td>
</tr>
<tr>
<td>Or</td>
<td>findByNameOrSex</td>
<td>where name= ? or sex=?</td>
</tr>
<tr>
<td>Is,Equal</td>
<td>findById,findByIdEquals</td>
<td>where id= ?</td>
</tr>
<tr>
<td>Between</td>
<td>findByIdBetween</td>
<td>where id between ? and ?</td>
</tr>
<tr>
<td>LessThan</td>
<td>findByIdLessThan</td>
<td>where id &lt; ?</td>
</tr>
<tr>
<td>LessThanEqual</td>
<td>findByIdLessThanEquals</td>
<td>where id &lt;= ?</td>
</tr>
<tr>
<td>GreaterThan</td>
<td>findByIdGreaterThan</td>
<td>where id &gt; ?</td>
</tr>
<tr>
<td>GreaterThanEqual</td>
<td>findByIdGreaterThanEquals</td>
<td>where id &gt; = ?</td>
</tr>
<tr>
<td>After</td>
<td>findByIdAfter</td>
<td>where id &gt; ?</td>
</tr>
<tr>
<td>Before</td>
<td>findByIdBefore</td>
<td>where id &lt; ?</td>
</tr>
<tr>
<td>IsNull</td>
<td>findByNameIsNull</td>
<td>where name is null</td>
</tr>
<tr>
<td>isNotNull,Not</td>
<td>findByNameNotNull</td>
<td>where name is not</td>
</tr>
<tr>
<td>Like</td>
<td>findByNameLike</td>
<td>where name like ?</td>
</tr>
<tr>
<td>NotLike</td>
<td>findByNameNotLike</td>
<td>where name not like ?</td>
</tr>
<tr>
<td>StartingWith</td>
<td>findByNameStartingWith</td>
<td>where name like &lsquo;?%&rsquo;</td>
</tr>
<tr>
<td>EndingWith</td>
<td>findByNameEndingWith</td>
<td>where name like &lsquo;%?&rsquo;</td>
</tr>
<tr>
<td>Containing</td>
<td>findByNameContaining</td>
<td>where name like &lsquo;%?%&rsquo;</td>
</tr>
<tr>
<td>OrderBy</td>
<td>findByIdOrderByXDesc</td>
<td>where id=? order by x desc</td>
</tr>
<tr>
<td>Not</td>
<td>findByNameNot</td>
<td>where name &lt;&gt; ?</td>
</tr>
<tr>
<td>In</td>
<td>findByIdIn(Collection&lt;?&gt; c)</td>
<td>where id in (?)</td>
</tr>
<tr>
<td>NotIn</td>
<td>findByIdNotIn(Collection&lt;?&gt; c)</td>
<td>where id not in (?)</td>
</tr>
<tr>
<td>True</td>
<td>findByAaaTue</td>
<td>where aaa = true</td>
</tr>
<tr>
<td>False</td>
<td>findByAaaFalse</td>
<td>where aaa = false</td>
</tr>
<tr>
<td>IgnoreCase</td>
<td>findByNameIgnoreCase</td>
<td>where UPPER(name)=UPPER(?)</td>
</tr>
</tbody>
</table>
<p>参考：https://docs.spring.io/spring-data/jpa/docs/1.11.22.RELEASE/reference/html/#jpa.query-methods.query-creation</p>
<p>示例：</p>
<pre><code class="language-java">//省……
</code></pre>
<p>总之一句话，DAO 接口继承 Repository 接口，然后在 DAO 接口中写的方法名要遵循命名规则</p>
<h2 id="2基于-query-注解查询">2）基于 @Query 注解查询</h2>
<p>官方示例：https://docs.spring.io/spring-data/jpa/docs/1.11.22.RELEASE/reference/html/#jpa.query-methods.at-query</p>
<p>我的示例：</p>
<pre><code class="language-java">public interface UserDao extends Repository&lt;User, Integer&gt; {
    //JPQL
    @Query(value = &quot;select u from User u where u.name = ?1&quot;)
    List&lt;User&gt; queryUserByName(String name);

    //SQL
    @Query(value = &quot;select * from user where name = ? &quot;,nativeQuery = true)
    List&lt;User&gt; queryUserByName2(String name);
}
</code></pre>
<pre><code class="language-java">    @Test
    public void test1(){
        List&lt;User&gt; userList = usersDao.queryUserByName(&quot;王五&quot;);
        for (User u : userList) {
            System.out.println(u.getName());
        }
    }
</code></pre>
<h2 id="3基于-query-注解执行更新删除操作">3）基于 @Query 注解执行更新、删除操作</h2>
<pre><code class="language-java">public interface UserDao extends Repository&lt;User, Integer&gt; {
    //update
    @Modifying
    @Query(&quot;update User u set u.name = ?1 where u.id = ?2&quot;)
    int updateUserName(String newName, Integer id);

    //delete
    @Modifying
    @Query(&quot;delete from User u where u.id = ?1&quot;)
    int deleteUser(Integer id);
}
</code></pre>
<pre><code class="language-java">    //更新用户
    @Test
    @Transactional// 在测试类对于事务提交方式默认的是回滚。
    @Rollback(false)//取消自动回滚
    public void test2(){
        this.usersDao.updateUserName(&quot;李想&quot;, 46);
    }

    //删除
    @Test
    @Transactional// 在测试类对于事务提交方式默认的是回滚。
    @Rollback(false)//取消自动回滚
    public void test3(){
        this.usersDao.deleteUser(46);
    }
</code></pre>
<p>官方示例：https://docs.spring.io/spring-data/jpa/docs/1.11.22.RELEASE/reference/html/#jpa.modifying-queries</p>
<h1 id="crudrepository-接口">CrudRepository 接口</h1>
<h2 id="crud-操作">CRUD 操作</h2>
<pre><code class="language-java">public interface UserDao extends CrudRepository&lt;User, Integer&gt; {

}
</code></pre>
<pre><code class="language-java">@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(&quot;classpath:applicationContext.xml&quot;)
public class UsersDaoImplTest {
    @Autowired
    private UserDao usersDao;

    /**
     * 添加单条数据
     *
     * 使用CrudRepository，不用添加事务，因为它已经添加
     */
    @Test
    public void test1(){
        User user = new User();
        user.setName(&quot;张飞&quot;);
        this.usersDao.save(user);
    }

    /**
     * 批量添加
     *
     * JDK中的集合都实现了 Iterable 接口，所以可以将集合作为入参
     */
    @Test
    public void test2(){
        User user = new User();
        user.setName(&quot;张小飞&quot;);

        User user1 = new User();
        user1.setName(&quot;王二虎&quot;);

        ArrayList&lt;User&gt; list = new ArrayList&lt;&gt;();
        list.add(user);
        list.add(user1);

        this.usersDao.save(list);
    }

    /**
     * 查找单条数据
     */
    @Test
    public void test3(){
        User user = this.usersDao.findOne(50);
        System.out.println(user);
    }

    /**
     * 查找多条数据
     */
    @Test
    public void test4(){
        List&lt;User&gt; list = (List) this.usersDao.findAll();
        for (User u : list) {
            System.out.println(u);
        }
    }

    /**
     * 更新方式一
     */
    @Test
    public void test5(){
        User user = this.usersDao.findOne(48);
        user.setName(&quot;王小小&quot;);
        this.usersDao.save(user);
    }

    /**
     * 更新方式二
     */
    @Test
    @Transactional
    @Rollback(false)
    public void test6(){
        User user = this.usersDao.findOne(49);//持久化状态
        user.setName(&quot;王小五&quot;);
        //this.usersDao.save(user);//不需要执行保存，但在测试类中要开事务
    }
}
</code></pre>
<h1 id="pagingandsortingrepository-接口">PagingAndSortingRepository 接口</h1>
<p>PagingAndSortingRepository 接口对表中的所有数据执行分页、排序操作，不是对一部分操作，而是所有数据。</p>
<h2 id="分页">分页</h2>
<pre><code class="language-java">public interface UserDao extends PagingAndSortingRepository&lt;User, Integer&gt; {

}
</code></pre>
<pre><code class="language-java">@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(&quot;classpath:applicationContext.xml&quot;)
public class UsersDaoImplTest {
    @Autowired
    private UserDao usersDao;

    @Test
    public void test(){
        int page = 0;//当前页，索引从0开始
        int size = 5;//每页条数
        Pageable pageable = new PageRequest(page,size);
        Page&lt;User&gt; p = this.usersDao.findAll(pageable);
        System.out.println(&quot;总条数：&quot;+p.getTotalElements());
        System.out.println(&quot;总页数：&quot;+p.getTotalPages());
        List&lt;User&gt; userList = p.getContent();
        for (User u : userList) {
            System.out.println(u);
        }
    }
}
</code></pre>
<h2 id="排序">排序</h2>
<pre><code class="language-java">    /**
     * 对单列排序
     */
    @Test
    public void test2(){
        //sort对象封装了排序规则和指定排序字段（对象的属性）
        //direction：排序规则，升序、降序
        //properties：根据哪个字段来排序
        Sort sort = new Sort(Sort.Direction.ASC, &quot;id&quot;);
        List&lt;User&gt; list = (List&lt;User&gt;) this.usersDao.findAll(sort);
        for (User u : list) {
            System.out.println(u);
        }
    }

    /**
     * 对多列排序
     */
    @Test
    public void test3(){
        //sort对象封装了排序规则和指定排序字段（对象的属性）
        //direction：排序规则，升序、降序
        //properties：根据哪个字段来排序
        Sort.Order order1 = new Sort.Order(Sort.Direction.ASC, &quot;id&quot;);
        Sort.Order order2 = new Sort.Order(Sort.Direction.DESC, &quot;name&quot;);
        Sort sort = new Sort(order1,order2);
        List&lt;User&gt; list = (List&lt;User&gt;) this.usersDao.findAll(sort);
        for (User u : list) {
            System.out.println(u);
        }
    }
</code></pre>
<h1 id="jparepository-接口">JpaRepository 接口</h1>
<p>JpaRepository 接口的最大作用是对父接口的返回值做适配处理（很多返回值是 List ）</p>
<p>开发中推荐继承 JpaRepository 接口，而不是继承上面的父接口。</p>
<h1 id="jpaspecificationexecutor-接口">JpaSpecificationExecutor 接口</h1>
<p>JpaSpecificationExecutor 接口的主要作用：完成多条件查询，并且支持分页与排序</p>
<p>不能单独使用，需要结合其它接口来使用</p>
<pre><code class="language-java">public interface UserDao extends JpaRepository&lt;User, Integer&gt;,JpaSpecificationExecutor&lt;User&gt; {

}
</code></pre>
<h2 id="单条件查询">单条件查询</h2>
<pre><code class="language-java">@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(&quot;classpath:applicationContext.xml&quot;)
public class UsersDaoImplTest {
    @Autowired
    private UserDao userDao;

    /**
     * 单条件查询
     *
     *需求：根据用户姓名查询数据
     */
    @Test
    public void test1(){
        Specification&lt;User&gt; spec = new Specification&lt;User&gt;() {
            /**
             * @param root：根对象，封装了查询条件的对象
             * @param criteriaQuery：定义了一个基本的查询.一般不使用
             * @param criteriaBuilder：创建一个查询条件
             *
             * @return Predicate:定义了查询条件
             */
            @Override
            public Predicate toPredicate(Root&lt;User&gt; root, CriteriaQuery&lt;?&gt; criteriaQuery, CriteriaBuilder criteriaBuilder) {
                Predicate pre = criteriaBuilder.equal(root.get(&quot;name&quot;), &quot;王五&quot;);
                return pre;
            }
        };
        List&lt;User&gt; list = this.userDao.findAll(spec);
        for (User u : list) {
            System.out.println(u);
        }
    }
}
</code></pre>
<h2 id="多条件查询">多条件查询</h2>
<pre><code class="language-java">    /**
     * 多条件查询方式一
     *
     * 需求：使用用户姓名以及年龄查询数据
     */
    @Test
    public void test2(){
        Specification&lt;User&gt; spec = new Specification&lt;User&gt;() {
            @Override
            public Predicate toPredicate(Root&lt;User&gt; root, CriteriaQuery&lt;?&gt; criteriaQuery, CriteriaBuilder cb) {
                List&lt;Predicate&gt; list = new ArrayList&lt;&gt;();
                list.add(cb.equal(root.get(&quot;name&quot;),&quot;王五&quot;));
                list.add(cb.equal(root.get(&quot;age&quot;),24));//此时条件之间是没有任何关系的。
                Predicate[] arr = new Predicate[list.size()];
                return cb.and(list.toArray(arr));
            }
        };
        List&lt;User&gt; list = this.userDao.findAll(spec);
        for (User u : list) {
            System.out.println(u);
        }
    }

    /**
     * 多条件查询方式二
     *
     * 需求：使用用户姓名或者年龄查询数据
     */
    @Test
    public void test3(){
        Specification&lt;User&gt; spec = new Specification&lt;User&gt;() {
            @Override
            public Predicate toPredicate(Root&lt;User&gt; root, CriteriaQuery&lt;?&gt; criteriaQuery, CriteriaBuilder cb) {
                return cb.or(cb.equal(root.get(&quot;name&quot;),&quot;王五&quot;),cb.equal(root.get(&quot;age&quot;), 25));
            }
        };
        List&lt;User&gt; list = this.userDao.findAll(spec);
        for (User u : list) {
            System.out.println(u);
        }
    }
</code></pre>
<h2 id="分页-1">分页</h2>
<pre><code class="language-java">    /**
     * 分页
     *
     * 需求：查询王姓用户，并且做分页处理
     */
    @Test
    public void test4(){
        Specification&lt;User&gt; spec = new Specification&lt;User&gt;() {
            @Override
            public Predicate toPredicate(Root&lt;User&gt; root, CriteriaQuery&lt;?&gt; criteriaQuery, CriteriaBuilder cb) {
                return cb.like(root.get(&quot;name&quot;).as(String.class),&quot;王%&quot;);
            }
        };
        //分页
        Pageable pageable = new PageRequest(0, 2);
        Page&lt;User&gt; page = this.userDao.findAll(spec, pageable);
        System.out.println(&quot;总条数：&quot;+page.getTotalElements());
        System.out.println(&quot;总页数：&quot;+page.getTotalPages());
        List&lt;User&gt; list = page.getContent();
        for (User u : list) {
            System.out.println(u);
        }
    }
</code></pre>
<h2 id="排序-1">排序</h2>
<pre><code class="language-java">    /**
     * 排序
     *
     * 需求：查询数据库中王姓的用户，并且根据用户id 做倒序排序
     */
    @Test
    public void test5(){
        Specification&lt;User&gt; spec = new Specification&lt;User&gt;() {
            @Override
            public Predicate toPredicate(Root&lt;User&gt; root, CriteriaQuery&lt;?&gt; criteriaQuery, CriteriaBuilder cb) {
                return cb.like(root.get(&quot;name&quot;).as(String.class),&quot;王%&quot;);
            }
        };
        //排序
        Sort sort = new Sort(Sort.Direction.DESC,&quot;id&quot;);
        List&lt;User&gt; list = this.userDao.findAll(spec, sort);
        for (User u : list) {
            System.out.println(u);
        }
    }
</code></pre>
<h2 id="分页与排序">分页与排序</h2>
<pre><code class="language-java">    /**
     * 分页与排序
     *
     * 需求：查询数据库中王姓的用户，做分页处理，并且根据用户id 做倒序排序
     */
    @Test
    public void test6(){
        //排序等定义
        Sort sort = new Sort(Sort.Direction.DESC,&quot;id&quot;);
        //分页的定义
        Pageable pageable = new PageRequest(0,5, sort);
        //查询条件
        Specification&lt;User&gt; spec = new Specification&lt;User&gt;() {
            @Override
            public Predicate toPredicate(Root&lt;User&gt; root,
                                         CriteriaQuery&lt;?&gt; query, CriteriaBuilder cb) {
                return cb.like(root.get(&quot;name&quot;).as(String.class),&quot;王%&quot;);
            }
        };
        Page&lt;User&gt; page = this.userDao.findAll(spec, pageable);
        System.out.println(&quot;总条数：&quot;+page.getTotalElements());
        System.out.println(&quot;总页数：&quot;+page.getTotalPages());
        List&lt;User&gt; list = page.getContent();
        for (User user : list) {
            System.out.println(user);
        }
    }
</code></pre>
<h2 id="总结">总结</h2>
<p>在上面示例中，Specification 中的参数都是写死的，不符合实际。在实际开发中参数由 DAO 入参传入，类似：</p>
<pre><code class="language-java">public List&lt;WeChatGzUserInfoEntity&gt; findByCondition(Date minDate, Date maxDate, String nickname){
        List&lt;WeChatGzUserInfoEntity&gt; resultList = null;
        Specification querySpecifi = new Specification&lt;WeChatGzUserInfoEntity&gt;() {
            @Override
            public Predicate toPredicate(Root&lt;WeChatGzUserInfoEntity&gt; root, CriteriaQuery&lt;?&gt; criteriaQuery, CriteriaBuilder criteriaBuilder) {

                List&lt;Predicate&gt; predicates = new ArrayList&lt;&gt;();
                if(null != minDate){
                    predicates.add(criteriaBuilder.greaterThan(root.get(&quot;subscribeTime&quot;), minDate));
                }
                if(null != maxDate){
                    predicates.add(criteriaBuilder.lessThan(root.get(&quot;subscribeTime&quot;), maxDate));
                }
                if(null != nickname){
                    predicates.add(criteriaBuilder.like(root.get(&quot;nickname&quot;), &quot;%&quot;+nickname+&quot;%&quot;));
                }
                return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
            }
        };
        resultList =  this.weChatGzUserInfoRepository.findAll(querySpecifi);
        return resultList;
    }
</code></pre>
<p>参考：http://www.cnblogs.com/derry9005/p/6282571.html</p>
<h1 id="自定义-repository-接口">自定义 Repository 接口</h1>
<p>目的：上面的5个接口不能满足我们的需求时，就自定义 Repository 接口。</p>
<p>怎么做呢？</p>
<p>1）创建自定义接口</p>
<pre><code class="language-java">public interface UserRepository {
    public User findUserById(Integer id);
}
</code></pre>
<p>2）使用自定义接口</p>
<p>使用上面自定义的接口</p>
<pre><code class="language-java">public interface UserDao extends JpaRepository&lt;User, Integer&gt;,JpaSpecificationExecutor&lt;User&gt;,UserRepository {

}
</code></pre>
<p>3）创建接口实现类</p>
<p>实现的接口是 UserDao，即实现将要交给 JPA 产生代理的接口；接口命名规则：以 Impl 结尾。</p>
<p><code>implements UserRepository</code> 其实就是实现 UserDao 接口，因为其它5个接口不用我们实现。</p>
<pre><code class="language-java">public class UserDaoImpl implements UserRepository {

    @PersistenceContext(name=&quot;entityManagerFactory&quot;)
    EntityManager em;

    @Override
    public User findUserById(Integer id) {
        System.out.println(&quot;MyRepository.......&quot;);
        return em.find(User.class,id);
    }
}
</code></pre>
<p>4）测试</p>
<p>测试跟前5个接口没有区别</p>
<pre><code class="language-java">@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(&quot;classpath:applicationContext.xml&quot;)
public class UsersDaoImplTest {
    @Autowired
    private UserDao userDao;

    @Test
    public void test(){
        User user = this.userDao.findUserById(10);
        System.out.println(user);
    }
}
</code></pre>
<p>参考自己的代码：spring-data-jpa-myrepository</p>
<h1 id="关联映射操作">关联映射操作</h1>
<h2 id="一对一">一对一</h2>
<p>需求：用户与角色的一对一的关联关系</p>
<p><img src="https://gitee.com/rulerLwx/PicGo/raw/master/img/20200708092455.png" alt=""></p>
<p>在 User 端维护外键。</p>
<h2 id="一对多">一对多</h2>
<p>需求：从角色到用户的一对多关联关系</p>
<p>梳理关系：一个角色可以赋给多个用户，多个用户可以拥有一个角色（一个用户只能拥有一个角色） —— 20190520。</p>
<p><img src="https://gitee.com/rulerLwx/PicGo/raw/master/img/20200708092514.png" alt=""></p>
<p>在多的一方（User）维护外键</p>
<h2 id="多对多">多对多</h2>
<p>需求：一个角色可以拥有多个菜单，一个菜单可以分配多个角色。多对多的关联关系。</p>
<p><img src="https://gitee.com/rulerLwx/PicGo/raw/master/img/20200708092533.png" alt=""></p>
<p>中间表在哪边配都一样</p>
<p><code>@ManyToMany(cascade = CascadeType.PERSIST,fetch = FetchType.EAGER)</code> 开启关联操作、关闭延迟加载</p>
<hr>
<p>更多知识可以阅读《Spring Data JPA从入门到精通》等书</p>

    </div>
    <div class="article-footer">
<blockquote class="mt-2x">
  <ul class="post-copyright list-unstyled">
    <li class="post-copyright-link hidden-xs">
      <strong>Permalink: </strong>
      <a href="https://rulerLwx.gitee.io/2019/08/java-framework-spring-data-jpa/" title="Java-framework-Spring-Data-JPA" target="_blank" rel="external">https://rulerLwx.gitee.io/2019/08/java-framework-spring-data-jpa/</a>
    </li>
    <li class="post-copyright-license">
      <strong>License：</strong><a href="http://creativecommons.org/licenses/by/4.0/deed.zh" target="_blank" rel="external">CC BY 4.0 CN</a>
    </li>
  </ul>
</blockquote>

<div class="panel panel-default panel-badger">
  <div class="panel-body">
    <figure class="media">
      <div class="media-left">
        <a href="https://gitee.com/rulerLwx" target="_blank" class="img-burn thumb-sm visible-lg">
          <img src="https://rulerLwx.gitee.io/avatar.png" class="img-rounded w-full" alt="">
        </a>
      </div>
      <div class="media-body">
        <h3 class="media-heading"><a href="https://gitee.com/rulerLwx" target="_blank"><span class="text-dark">rulerLwx</span><small class="ml-1x">thinking...</small></a></h3>
        <div>Good Good Study, Day Day Up~</div>
      </div>
    </figure>
  </div>
</div>
    </div>
  </article>
<section id="comments">
    <div id="vcomments"></div>
</section>

</div><nav class="bar bar-footer clearfix" data-stick-bottom>
    <div class="bar-inner">
        <ul class="pager pull-left">
            <li class="prev">
                <a href="https://rulerLwx.gitee.io/2019/08/java-framework-springmvc-3-%E6%95%B4%E5%90%88%E5%BC%80%E5%8F%91/" title="Java-framework-SpringMVC-3-整合开发"><i
                        class="icon icon-angle-left"
                        aria-hidden="true"></i><span>&nbsp;&nbsp;Older</span></a>
            </li>
            <li class="next">
                <a href="https://rulerLwx.gitee.io/2019/08/java-framework-spring-data-redis/"
                    title="Java-framework-Spring-Data-Redis"><span>Newer&nbsp;&nbsp;</span><i
                        class="icon icon-angle-right" aria-hidden="true"></i></a>
            </li>
            
            <li class="toggle-toc">
                <a class="toggle-btn collapsed" data-toggle="collapse" href="#collapseToc" aria-expanded="false"
                    title="Catalogue" role="button">
                    <span>[&nbsp;</span><span>Catalogue</span>
                    <i class="text-collapsed icon icon-anchor"></i>
                    <i class="text-in icon icon-close"></i>
                    <span>]</span>
                </a>
            </li>
        </ul>
        <div class="bar-right">
            <div class="share-component" data-sites="weibo,qq,wechat"
                data-mobile-sites="weibo,qq,qzone"></div>
        </div>
    </div>
</nav>

</main><footer class="footer" itemscope itemtype="http://schema.org/WPFooter">
<ul class="social-links">
    <li><a href="https://gitee.com/rulerLwx" target="_blank" title="gitee" data-toggle=tooltip data-placement=top >
            <i class="icon icon-gitee"></i></a></li>
    <li><a href="https://github.com/wolf-lea" target="_blank" title="github" data-toggle=tooltip data-placement=top >
            <i class="icon icon-github"></i></a></li>
</ul>
  <div class="copyright">
    &copy;2017  -
    2020
    <div class="publishby">
        Theme by <a href="https://github.com/xiaoheiAh" target="_blank"> xiaoheiAh </a>base on<a href="https://github.com/xiaoheiAh/hugo-theme-pure" target="_blank"> pure</a>.
    </div>
  </div>
</footer>

<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/MathJax.js?config=TeX-MML-AM_SVG"></script>
<script type="text/x-mathjax-config">
    MathJax.Hub.Config({
            showMathMenu: false, //disables context menu
            tex2jax: {
            inlineMath: [ ['$','$'], ['\\(','\\)'] ]
           }
    });
</script>


<script src="https://cdn.jsdelivr.net/npm/jquery@3.4.1/dist/jquery.min.js"></script>
<script>
    window.jQuery || document.write('<script src="js/jquery.min.js"><\/script>')
</script>
<script type="text/javascript" src="https://cdn.staticfile.org/highlight.js/9.15.10/highlight.min.js"></script>
<script type="text/javascript" src="https://cdn.staticfile.org/highlight.js/9.15.10/languages/python.min.js" defer></script>
<script type="text/javascript" src="https://cdn.staticfile.org/highlight.js/9.15.10/languages/javascript.min.js" defer></script><script>
    hljs.configure({
        tabReplace: '    ', 
        classPrefix: ''     
        
    })
    hljs.initHighlightingOnLoad();
</script>
<script src="https://rulerLwx.gitee.io/js/application.min.bdeb64b910570b6c41badc6a05b7afb0c8ad9efd8525de3c7257d59e786326a3.js"></script>
<script src="https://rulerLwx.gitee.io/js/plugin.min.51ff8c7317566f82259170fa36e09c4493adc9b9378b427a01ad3f017ebac7dd.js"></script>

<script>
    (function (window) {
        var INSIGHT_CONFIG = {
            TRANSLATION: {
                POSTS: 'Posts',
                PAGES: 'Pages',
                CATEGORIES: 'Categories',
                TAGS: 'Tags',
                UNTITLED: '(Untitled)',
            },
            ROOT_URL: 'https:\/\/rulerLwx.gitee.io',
            CONTENT_URL: 'https:\/\/rulerLwx.gitee.io\/searchindex.json ',
        };
        window.INSIGHT_CONFIG = INSIGHT_CONFIG;
    })(window);
</script>
<script type="text/javascript" src="https://rulerLwx.gitee.io/js/insight.min.a343cd9a5a7698336b28ef3a7c16a3a1b1d2d5fb17dc8ed04022bbe08cc5459073a15bdafa3a8a58cdd56080784bdd69fa70b1ae8597565c799c57ed00f0e120.js" defer></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.4.2/tocbot.min.js"></script>
<script>
    tocbot.init({
        
        tocSelector: '.js-toc',
        
        contentSelector: '.js-toc-content',
        
        headingSelector: 'h1, h2, h3',
        
        hasInnerContainers: true,
    });
</script>

<script src="https://cdn1.lncld.net/static/js/3.0.4/av-min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/valine"></script>
<script type="text/javascript">
    var GUEST = ['nick', 'mail', 'link'];
    var meta = 'nick,mail';
    meta = meta.split(',').filter(function (item) {
        return GUEST.indexOf(item) > -1;
    });
    new Valine({
        el: '#vcomments',
        verify: null ,
        notify: null ,
        appId: 'IyAB0PSPRazTPDxitO1ddQ7O-gzGzoHsz',
        appKey: '5rBJTq4KidYF33eXwvRVhtEH',
        placeholder: 'enjoy~',
        avatar: 'mm',
        meta: meta,
        pageSize: '10' || 10,
        visitor: false 
});
</script>

  </body>
</html>
